/**
 * JAVACC DEMO 1.0
 */
package com.apache.info.service.impl;

import com.apache.api.manager.PluginConnector;
import com.apache.api.vo.ParamsVo;
import com.apache.cache.util.Validator;
import com.apache.database.db.IDao;
import com.apache.database.model.MethodParam;
import com.apache.database.model.Page;
import com.apache.exception.BusinessException;
import com.apache.info.entity.PubMetadata;
import com.apache.info.manager.InfoReleaseManager;
import com.apache.info.manager.PubSortInfoManager;
import com.apache.info.util.InfoMap;
import com.apache.info.util.MessageUtil;
import com.apache.tools.StrUtil;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description:  动态表单查询manager实现
 *
 * @author Hou Dayu 创建时间：2016-8-27
 */
public class InfoReleaseManagerImpl implements InfoReleaseManager {

	private Logger log = Logger.getLogger(InfoReleaseManagerImpl.class);

	protected IDao infoReleaseDao;

	protected Map<String, PluginConnector> plugins = new HashMap<String, PluginConnector>();

	protected final String spanceName = "com.apache.info.entity.InfoRelease";

	protected PubSortInfoManager pubSortInfoManager;

	public void setInfoReleaseDao(IDao infoReleaseDao) {
		this.infoReleaseDao = infoReleaseDao;
	}

	public void setPlugins(Map<String, PluginConnector> plugins) {
		this.plugins = plugins;
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 *
	 * @see com.apache.info.manager.UnityBaseManager#getPageInfo(ParamsVo)
	 */
	public Page getPageInfo(ParamsVo<Object> vo) {
		String key = Validator.getDefaultStr(vo.getMethodKey(), "InfoRelease");
		MethodParam param = new MethodParam(key, "", "", spanceName);
		String dyncSql = String.valueOf(vo.getParams("dyncSql"));
		int pageSize = Integer.valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageSize")), "10"));
		int pageIndex = Integer.valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageIndex")), "1"));
		param.setPageIndex(pageIndex);
		param.setPageSize(pageSize);
		Page page = new Page();
		List<PubMetadata> metadata = (List) vo.getParams("metadatas");
		if (Validator.isNull(dyncSql)) {
			Map<String, String> map = (Map) vo.getParams("params");
			map.put("DatabaseType", String.valueOf(vo.getParams("DatabaseType")));
			String sql = getPubSql(map, metadata, 4);
			param.setParams("dyncSql", sql);
		} else {
			param.setParams("dyncSql", String.valueOf(vo.getParams("dyncSql")));
		}
		page = infoReleaseDao.pageSelect(param);
		//		if (!Validator.isEmpty(metadata)) {
		//			List list = getResultList(metadata, page.getPageObjects());
		//			page.setPageObjects(list);
		//		}
		return page;
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 *
	 * @see com.apache.api.manager.BaseManager#countInfo(ParamsVo)
	 */
	public long countInfo(ParamsVo<Object> vo) {
		String key = Validator.getDefaultStr(vo.getMethodKey(), "InfoRelease");
		MethodParam param = new MethodParam(key, "", "", spanceName);
		String dyncSql = String.valueOf(vo.getParams("dyncSql"));
		if (Validator.isNull(dyncSql)) {
			List<PubMetadata> metadata = (List) vo.getParams("metadatas");
			Map<String, String> map = (Map) vo.getParams("params");
			map.put("DatabaseType", String.valueOf(vo.getParams("DatabaseType")));
			String sql = getPubSql(map, metadata, 5);
			param.setParams("dyncSql", sql);
		} else {
			param.setParams("dyncSql", String.valueOf(vo.getParams("dyncSql")));
		}
		return infoReleaseDao.count(param);
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 *
	 * @see com.apache.api.manager.BaseManager#execute(ParamsVo)
	 */
	public Object execute(ParamsVo<Object> vo) {
		String key = vo.getKey();
		try {
			if (!Validator.isEmpty(plugins.get(key))) {
				return plugins.get(key).execute(vo);
			}
		} catch (Exception e) {
			throw new BusinessException(key, e);
		}
		return null;
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 *
	 * @see com.apache.api.manager.BaseManager#getInfoById(ParamsVo)
	 */
	public Object getInfoById(ParamsVo<Object> vo) {
		String key = Validator.getDefaultStr(vo.getMethodKey(), "InfoRelease");
		MethodParam param = new MethodParam(key, "", "", spanceName);
		String dyncSql = String.valueOf(vo.getParams("dyncSql"));
		List<PubMetadata> metadata = (List) vo.getParams("metadatas");
		Object obj = null;
		if (Validator.isNull(dyncSql)) {
			Map<String, String> map = (Map) vo.getParams("params");
			map.put("DatabaseType", String.valueOf(vo.getParams("DatabaseType")));
			String sql = getPubSql(map, metadata, 4);
			param.setParams("dyncSql", sql);
		} else {
			param.setParams("dyncSql", String.valueOf(vo.getParams("dyncSql")));
		}
		obj = infoReleaseDao.selectSingle(param);
		//		if (!Validator.isEmpty(obj) && !Validator.isEmpty(metadata)) {
		//			return getResultMap(metadata, (Map) obj);
		//		}
		return obj;
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 *
	 * @see com.apache.api.manager.BaseManager#getList(ParamsVo)
	 */
	public List<Object> getList(ParamsVo<Object> vo) {
		String key = Validator.getDefaultStr(vo.getMethodKey(), "InfoRelease");
		MethodParam param = new MethodParam(key, "", "", spanceName);
		String dyncSql = String.valueOf(vo.getParams("dyncSql"));
		List<PubMetadata> metadata = (List) vo.getParams("metadatas");
		if (Validator.isNull(dyncSql)) {
			Map<String, String> map = (Map) vo.getParams("params");
			map.put("DatabaseType", String.valueOf(vo.getParams("DatabaseType")));
			String sql = getPubSql(map, metadata, 4);
			param.setParams("dyncSql", sql);
		} else {
			param.setParams("dyncSql", String.valueOf(vo.getParams("dyncSql")));
			return infoReleaseDao.select(param);
		}
		List list = infoReleaseDao.select(param);
		//		if (!Validator.isEmpty(metadata))
		//			return getResultList(metadata, list);
		return list;
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 *
	 * @see com.apache.api.manager.BaseManager#saveInfo(ParamsVo)
	 */
	public String saveInfo(ParamsVo<Object> vo) throws BusinessException {
		String key = Validator.getDefaultStr(vo.getMethodKey(), "InfoRelease");
		MethodParam param = new MethodParam(key, "", "", spanceName);
		String dyncSql = String.valueOf(vo.getParams("dyncSql"));
		if (Validator.isNull(dyncSql)) {
			List<PubMetadata> metadata = (List) vo.getParams("metadatas");
			Map<String, String> map = (Map) vo.getParams("params");
			map.put("DatabaseType", String.valueOf(vo.getParams("DatabaseType")));
			String sql = getPubSql(map, metadata, 1);
			param.setParams("dyncSql", sql);
		} else {
			String subDyncSql = String.valueOf(vo.getParams("subDyncSql"));
			if (Validator.isNotNull(subDyncSql)) {
				return String.valueOf(mainAndSubOpera(dyncSql, subDyncSql));
			}
			param.setParams("dyncSql", String.valueOf(vo.getParams("dyncSql")));
		}
		boolean mark = infoReleaseDao.edit(param);
		return String.valueOf(mark);
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 *
	 * @see com.apache.api.manager.BaseManager#deleteInfo(ParamsVo)
	 */
	public boolean deleteInfo(ParamsVo<Object> vo) throws BusinessException {
		String key = Validator.getDefaultStr(vo.getMethodKey(), "InfoRelease");
		MethodParam param = new MethodParam(key, "", "", spanceName);
		String dyncSql = String.valueOf(vo.getParams("dyncSql"));
		param.setDelete(true);
		if (Validator.isNull(dyncSql)) {
			List<PubMetadata> metadata = (List) vo.getParams("metadatas");
			Map<String, String> map = (Map) vo.getParams("params");
			map.put("DatabaseType", String.valueOf(vo.getParams("DatabaseType")));
			String sql = getPubSql(map, metadata, 3);
			param.setParams("dyncSql", sql);
			return infoReleaseDao.delete(param);
		} else {
			String subDyncSql = String.valueOf(vo.getParams("subDyncSql"));
			if (Validator.isNotNull(subDyncSql)) {
				return mainAndSubOpera(dyncSql, subDyncSql);
			}
			param.setParams("dyncSql", String.valueOf(vo.getParams("dyncSql")));
			infoReleaseDao.delete(param);
			//			if (!Validator.isEmpty(vo.getParams("sort"))) {
			//				PubSortInfo sort = (PubSortInfo) vo.getParams("sort");
			//				ParamsVo<PubSortInfo> svo = new ParamsVo<PubSortInfo>();
			//				sort.setSortStatus("0");
			//				svo.setObj(sort);
			//				pubSortInfoManager.editInfo(svo);
			//			}
		}
		return true;
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 *
	 * @see com.apache.api.manager.BaseManager#editInfo(ParamsVo)
	 */
	public boolean editInfo(ParamsVo<Object> vo) throws BusinessException {
		String key = Validator.getDefaultStr(vo.getMethodKey(), "InfoRelease");
		MethodParam param = new MethodParam(key, "", "", spanceName);
		String dyncSql = String.valueOf(vo.getParams("dyncSql"));
		if (Validator.isNull(dyncSql)) {
			List<PubMetadata> metadata = (List) vo.getParams("metadatas");
			Map<String, String> map = (Map) vo.getParams("params");
			map.put("DatabaseType", String.valueOf(vo.getParams("DatabaseType")));
			String sql = getPubSql(map, metadata, 2);
			param.setParams("dyncSql", sql);
			return infoReleaseDao.edit(param);
		} else {
			String subDyncSql = String.valueOf(vo.getParams("subDyncSql"));
			if (Validator.isNotNull(subDyncSql)) {
				return mainAndSubOpera(dyncSql, subDyncSql);
			}
			param.setParams("dyncSql", String.valueOf(vo.getParams("dyncSql")));
			boolean mark = true;
			infoReleaseDao.edit(param);
			//			if (!Validator.isEmpty(vo.getParams("sort"))) {
			//				PubSortInfo sort = (PubSortInfo) vo.getParams("sort");
			//				ParamsVo<PubSortInfo> svo = new ParamsVo<PubSortInfo>();
			//				sort.setSortStatus("1");
			//				svo.setObj(sort);
			//				mark = pubSortInfoManager.editInfo(svo);
			//			}
			return mark;
		}
	}

	/**
	 * description:  主子表增、删、改操作
	 *
	 * @param mainSql
	 * @param subSql
	 * @return
	 */
	private boolean mainAndSubOpera(String mainSql, String subSql) {
		MethodParam param = new MethodParam("InfoRelease", "", "", spanceName);
		param.setParams("dyncSql", mainSql);
		boolean mark = infoReleaseDao.edit(param);
		if (mark) {
			param.setParams("dyncSql", subSql);
			mark = infoReleaseDao.edit(param);
		}
		return mark;
	}

	private List getResultList(List<PubMetadata> metadata, List<Map<String, Object>> result) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		if (!Validator.isEmpty(result)) {
			for (Map<String, Object> map : result) {
				list.add(getResultMap(metadata, map));
			}
		}
		return list;
	}

	private Map<String, Object> getResultMap(List<PubMetadata> metadata, Map<String, Object> result) {
		Map<String, Object> map = new HashMap<String, Object>();
		for (PubMetadata pm : metadata) {
			if (!Validator.isEmpty(result.get(pm.getDataAttr().toUpperCase()))) {
				map.put(pm.getDataAttr(), result.get(pm.getDataAttr().toUpperCase()));
			}
		}
		return map;
	}

	/**
	 * description:  获取待执行sql
	 */
	private String getPubSql(Map<String, String> map, List<PubMetadata> metadata, int sqlType) {
		String sql = "";
		if (!Validator.isEmpty(metadata)) {
			//        String dbType = ConfigUtil.getInstance().getValueByKey("jdbc.properties", "database_type");
			String dbType = map.get("DatabaseType");
			if (StrUtil.isNull(dbType)) {
				dbType = MessageUtil.getDatabastType("plateform", "");
			}
			sql = sqlForOracle(metadata, map, sqlType, dbType);
		}
		log.info("getPubSql=" + sql);
		return sql;
	}

	/**
	 * description:  拼装待执行sql
	 */
	private String sqlForOracle(List<PubMetadata> metadata, Map<String, String> map, int sqlType, String dbType) {
		StringBuffer sb = new StringBuffer("");
		StringBuffer sb2 = new StringBuffer("");
		String tid = "";
		int i = 0;
		switch (sqlType) {
		case 1://新增
			sb.append("insert into " + map.get("tableName") + "( ");
			for (PubMetadata pm : metadata) {
				if (Validator.isNotNull(map.get(pm.getDataAttr()))) {
					if (i == 0) {
						sb.append(pm.getDataShortName());
						if ("1".equals(pm.getDataType()) || "2".equals(pm.getDataType())
								|| "3".equals(pm.getDataType())) {
							sb2.append(map.get(pm.getDataAttr()));
						} else if ("6".equals(pm.getDataType())) {
							sb2.append(dateSql(map.get(pm.getDataAttr()), dbType));
						} else {
							sb2.append("'" + map.get(pm.getDataAttr()) + "'");
						}
					} else {
						sb.append("," + pm.getDataShortName());
						if ("1".equals(pm.getDataType()) || "2".equals(pm.getDataType())
								|| "3".equals(pm.getDataType())) {
							sb2.append(" ," + map.get(pm.getDataAttr()));
						} else if ("6".equals(pm.getDataType())) {
							sb2.append("," + dateSql(map.get(pm.getDataAttr()), dbType));
						} else {
							sb2.append(" ,'" + map.get(pm.getDataAttr()) + "'");
						}
					}
					i++;
				}
			}
			sb.append(" ) values(" + sb2.toString() + ")");
			break;
		case 2://修改
			StringBuilder tids = new StringBuilder();
			sb.append("UPDATE " + map.get("tableName") + " SET ");
			for (PubMetadata pm : metadata) {
				if (Validator.isNotNull(map.get(pm.getDataAttr()))) {
					if ("4".equals(pm.getDataRestrict())) {//联合主键
						tids.append("and " + pm.getDataShortName() + "='" + map.get(pm.getDataAttr()) + "'");
						continue;
					} else if ("1".equals(pm.getDataRestrict())) {
						tid = pm.getDataShortName() + "='" + map.get(pm.getDataAttr()) + "'";
						continue;
					}
					if (i == 0) {
						if ("1".equals(pm.getDataType()) || "2".equals(pm.getDataType())
								|| "3".equals(pm.getDataType())) {
							sb2.append(pm.getDataShortName() + "=" + map.get(pm.getDataAttr()));
						} else if ("6".equals(pm.getDataType())) {
							sb2.append(pm.getDataShortName() + "=" + dateSql(map.get(pm.getDataAttr()), dbType));
						} else {
							sb2.append(pm.getDataShortName() + "='" + map.get(pm.getDataAttr()) + "'");
						}
					} else {
						if ("1".equals(pm.getDataType()) || "2".equals(pm.getDataType())
								|| "3".equals(pm.getDataType())) {
							sb2.append(pm.getDataShortName() + "=" + map.get(pm.getDataAttr()));
						} else if ("6".equals(pm.getDataType())) {
							sb2.append("," + pm.getDataShortName() + "=" + dateSql(map.get(pm.getDataAttr()), dbType));
						} else {
							sb2.append(" ," + pm.getDataShortName() + "='" + map.get(pm.getDataAttr()) + "'");
						}
					}
					i++;
				}
			}
			sb.append(sb2.toString());
			if (Validator.isNotNull(tid)) {
				sb.append(" where " + tid);
			} else {
				tids.deleteCharAt(3);
				sb.append(" where " + tids.toString());
			}
			break;
		case 3://删除
			sb.append("Delete from " + map.get("tableName"));
			for (PubMetadata pm : metadata) {
				if (Validator.isNotNull(map.get(pm.getDataAttr()))) {
					sb2.append(sqlWhere(pm, map.get(pm.getDataAttr()), i));
					i++;
				}
			}
			if (sb2.length() > 0) {
				sb.append(" where " + sb2.toString());
			}
			break;
		case 4://查询
			sb.append("select ");
			String orberBy = "";
			int k = 0;
			for (PubMetadata pm : metadata) {
				if (Validator.isNotNull(pm.getReserved1())) {
					orberBy += pm.getDataShortName() + " " + pm.getReserved1() + ",";
				}
				if (k == 0) {
					sb.append(pm.getDataShortName() + " as " + InfoMap.exChange(pm.getDataAttr()));//pm.getDataAttr());
				} else {
					sb.append("," + pm.getDataShortName() + " as " + InfoMap.exChange(pm.getDataAttr()));//pm.getDataAttr());
				}
				if (Validator.isNotNull(map.get(pm.getDataAttr()))) {
					sb2.append(sqlWhere(pm, map.get(pm.getDataAttr()), i));
					i++;
				}
				k++;
			}
			sb.append(" from " + map.get("tableName"));
			if (sb2.length() > 0) {
				sb.append(" where " + sb2.toString());
			}
			//自定义排序
			if (Validator.isNotNull(map.get("orderby"))) {
				sb.append(" order by " + map.get("orderby"));
			} else {
				if (Validator.isNotNull(orberBy)) {
					sb.append(" order by " + orberBy.substring(0, orberBy.length() - 1));
				}
			}
			break;
		case 5://取记录数
			sb.append("select");
			for (PubMetadata pm : metadata) {
				if ("1".equals(pm.getDataRestrict())) {
					tid = pm.getDataShortName();
				}
				if (Validator.isNotNull(map.get(pm.getDataAttr()))) {
					sb2.append(sqlWhere(pm, map.get(pm.getDataAttr()), i));
					i++;
				}
			}
			sb.append(" " + tid + " from " + map.get("tableName"));
			if (sb2.length() > 0) {
				sb.append(" where " + sb2.toString());
			}
			break;
		}
		return sb.toString();
	}

	private String dateSql(String value, String dbType) {
		String sql = "";
		if ("oracle".equals(dbType)) {
			sql = "to_date('" + value + "','yyyy-mm-dd hh24:mi:ss')";
		} else if ("sqlserver".equals(dbType)) {
			sql = "to_date('" + value + "','yyyy-mm-dd hh:mm:ss')";
		} else if ("mysql".equals(dbType)) {
			sql = "to_date('" + value + "','yyyy-mm-dd hh:mi:ss')";
		}
		return sql;//"'" + value + "'";
	}

	/**
	 * description:  拼装待执行sql条件
	 */
	private String sqlWhere(PubMetadata pm, String value, int num) {
		StringBuffer result = new StringBuffer("");
		if (num != 0) {
			result.append(" and ");
		}
		String filedName = pm.getDataShortName();
		if ("1".equals(pm.getDataType()) || "2".equals(pm.getDataType()) || "3".equals(pm.getDataType())) {
			//数字类型
			if (value.startsWith("between") || value.startsWith("in")) {
				result.append(filedName + " " + value);
			} else {
				result.append(filedName + "=" + value);
			}
		} else {
			//字符类型
			if (value.startsWith("like '%") || value.startsWith("in (")) {
				result.append(filedName + " " + value);
			} else {
				result.append(filedName + "='" + value + "'");
			}
		}
		//		String result = "";
		//		if (num == 0) {
		//			if ("1".equals(pm.getDataType()) || "2".equals(pm.getDataType()) || "3".equals(pm.getDataType())) {
		//				if (value.startsWith("between")) {
		//					result = pm.getDataShortName() + " " + value;
		//				} else {
		//					result = pm.getDataShortName() + "=" + value;
		//				}
		//			} else {
		//				if (value.startsWith("like '%")) {
		//					result = pm.getDataShortName() + " " + value;
		//				} else {
		//					result = pm.getDataShortName() + "='" + value + "'";
		//				}
		//			}
		//		} else {
		//			if ("1".equals(pm.getDataType()) || "2".equals(pm.getDataType()) || "3".equals(pm.getDataType())) {
		//				if (value.startsWith("between")) {
		//					result = " and " + pm.getDataShortName() + " " + value;
		//				} else {
		//					result = " and " + pm.getDataShortName() + "=" + value;
		//				}
		//			} else {
		//				if (value.startsWith("like '%")) {
		//					result = " and " + pm.getDataShortName() + " " + value;
		//				} else {
		//					result = " and " + pm.getDataShortName() + "='" + value + "'";
		//				}
		//			}
		//		}
		return result.toString();
	}

	public void setPubSortInfoManager(PubSortInfoManager pubSortInfoManager) {
		this.pubSortInfoManager = pubSortInfoManager;
	}

}
